﻿using ProjScan.Config;
using ProjScan.RecordManager;
using ProjScan.RecordManager.AssetData;
using ProjScan.ScanRule.Attr;
using ProjScan.Tools;
using System;
using UnityEngine;

namespace ProjScan.ScanRule.ArtAssets.Mesh
{
    [ArtAssetRuleAttr]
    internal class VertexDensityTooLarge : RecordRuleImp<MeshRenderingAssetData, MeshRenderingRecordManager>
    {
        private float maxDensity = 50f;

        private float distance;

        private float fov;

        protected override bool UseAssetDataCSVHeader => false;

        public VertexDensityTooLarge()
        {
            ArtAssetsCheckConfig artAssetsCheckConfig = Singleton<ConfigMgr>.Instance.GetConfig<ArtAssetsCheckConfig>() as ArtAssetsCheckConfig;
            maxDensity = artAssetsCheckConfig.vertexDensityMaxDensity;
            distance = artAssetsCheckConfig.vertexDensityDistance;
            fov = artAssetsCheckConfig.vertexDensityFov;
        }

        protected override string GetDetailCSVHeader()
        {
            return "Name,DirID,VertexDensity";
        }

        public override void CheckDirSetted()
        {
            if (SeparateDirSettingsEnabled)
            {
                if (target_configs == null || target_configs.Length == 0)
                {
                    ScanLog.UnityLogError("美术资源检测规则 " + GetType().Name + " 执行失败，未设置目标文件夹");
                }

                if (target_configs.Length == 1 && target_configs[0].assetPath.StartsWith("Assets/ArtCheckFolder"))
                {
                    ScanLog.UnityLogError("美术资源检测规则 " + GetType().Name + " 执行失败，未设置目标文件夹");
                }
            }
        }

        public override bool CheckSupportability(out string msg)
        {
            msg = "";
            return true;
        }

        public static float CheckVertexDensity(UnityEngine.Mesh mesh, float viewDistance, float fov)
        {
            float f = 2f * viewDistance * Mathf.Tan(fov * 0.5f * 0.01745329f);
            float num = mesh.bounds.size.sqrMagnitude / Mathf.Pow(f, 2f);
            return 0.0001f * (float)mesh.vertexCount / num;
        }

        protected override bool IsOK(MeshRenderingAssetData assetData)
        {
            float num = 0f;
            try
            {
                num = CheckVertexDensity(assetData.asset, distance, fov);
            }
            catch (Exception exception_)
            {
                ScanLog.Instance.LogException(exception_, "VertexDensityTooLarge.CheckVertexDensity", "Return FAILED");
                assetData.vertexDensity = "FAILED";
                return false;
            }

            assetData.vertexDensity = num.ToString();
            return num <= maxDensity;
        }
    }
}